import 'dart:async';
import 'dart:convert';
import 'package:flutter/foundation.dart';
import 'package:web_socket_channel/web_socket_channel.dart';
import 'package:web_socket_channel/io.dart';
import '../utils/storage_util.dart';

/// WebSocket消息类型枚举
enum WebSocketMessageType {
  private,    // 私聊消息
  group,      // 群聊消息
  admin,      // 管理员消息
  notification, // 通知消息
}

/// WebSocket消息模型
class WebSocketMessage {
  final String type;
  final String? to;
  final String? pondId;
  final Map<String, dynamic> content;
  final bool read;
  final DateTime timestamp;

  WebSocketMessage({
    required this.type,
    this.to,
    this.pondId,
    required this.content,
    this.read = false,
    DateTime? timestamp,
  }) : timestamp = timestamp ?? DateTime.now();

  factory WebSocketMessage.fromJson(Map<String, dynamic> json) {
    return WebSocketMessage(
      type: json['type'] ?? 'notification',
      to: json['to'],
      pondId: json['pondId'],
      content: json['content'] ?? {},
      read: json['read'] ?? false,
      timestamp: json['timestamp'] != null 
          ? DateTime.parse(json['timestamp'])
          : DateTime.now(),
    );
  }

  Map<String, dynamic> toJson() {
    return {
      'type': type,
      if (to != null) 'to': to,
      if (pondId != null) 'pondId': pondId,
      'content': content,
      'read': read,
      'timestamp': timestamp.toIso8601String(),
    };
  }
}

/// WebSocket服务类
class WebSocketService {
  static final WebSocketService _instance = WebSocketService._internal();
  factory WebSocketService() => _instance;
  WebSocketService._internal();

  
  WebSocketChannel? _channel;
  StreamSubscription? _subscription;
  Timer? _heartbeatTimer;
  Timer? _reconnectTimer;
  
  bool _isConnected = false;
  bool _isConnecting = false;
  int _reconnectAttempts = 0;
  static const int _maxReconnectAttempts = 5;
  static const Duration _reconnectDelay = Duration(seconds: 3);
  static const Duration _heartbeatInterval = Duration(seconds: 30);

  // 消息回调
  final StreamController<WebSocketMessage> _messageController = 
      StreamController<WebSocketMessage>.broadcast();
  
  // 连接状态回调
  final StreamController<bool> _connectionController = 
      StreamController<bool>.broadcast();

  /// 消息流
  Stream<WebSocketMessage> get messageStream => _messageController.stream;
  
  /// 连接状态流
  Stream<bool> get connectionStream => _connectionController.stream;
  
  /// 是否已连接
  bool get isConnected => _isConnected;

  /// 获取WebSocket服务器地址
  String _getWebSocketUrl() {
    if (kDebugMode) {
      return 'ws://192.168.110.109:8080/ws/notice';
    } else {
      return 'ws://118.196.25.232:8080/ws/notice';
    }
  }

  /// 连接WebSocket
  Future<void> connect({String? userId}) async {
    if (_isConnecting || _isConnected) {
      return;
    }

    _isConnecting = true;
    
    try {
      // 获取用户ID和token
      final token = await StorageUtil.getToken();
      if (token == null || token.isEmpty) {
        throw Exception('Token为空，无法建立WebSocket连接');
      }

      // 如果没有传入userId，尝试从存储中获取
      if (userId == null) {
        final userInfo = await StorageUtil.getUserInfo();
        if (userInfo != null) {
          // 这里需要根据实际的用户信息格式解析userId
          // 假设userInfo是JSON字符串格式
          try {
            final userMap = jsonDecode(userInfo);
            userId = userMap['userId']?.toString();
          } catch (e) {
          }
        }
      }

      if (userId == null) {
        throw Exception('用户ID为空，无法建立WebSocket连接');
      }

      // 构建WebSocket URL
      final wsUrl = '${_getWebSocketUrl()}?token=${Uri.encodeComponent(token)}&userId=$userId';
      
      
      // 创建WebSocket连接
      _channel = IOWebSocketChannel.connect(
        Uri.parse(wsUrl),
        protocols: ['websocket'],
      );

      // 监听消息
      _subscription = _channel!.stream.listen(
        _onMessage,
        onError: _onError,
        onDone: _onDisconnected,
      );

      _isConnected = true;
      _isConnecting = false;
      _reconnectAttempts = 0;
      
      _connectionController.add(true);
      
      // 启动心跳
      _startHeartbeat();
      
    } catch (e) {
      _isConnecting = false;
      _isConnected = false;
      _connectionController.add(false);
      
      // 自动重连
      _scheduleReconnect();
    }
  }

  /// 处理接收到的消息
  void _onMessage(dynamic data) {
    try {
      
      final Map<String, dynamic> messageData = jsonDecode(data);
      final message = WebSocketMessage.fromJson(messageData);
      
      _messageController.add(message);
      
    } catch (e) {
    }
  }

  /// 处理连接错误
  void _onError(error) {
    _isConnected = false;
    _connectionController.add(false);
    _scheduleReconnect();
  }

  /// 处理连接断开
  void _onDisconnected() {
    _isConnected = false;
    _connectionController.add(false);
    _stopHeartbeat();
    _scheduleReconnect();
  }

  /// 发送消息
  Future<void> sendMessage(WebSocketMessage message) async {
    if (!_isConnected || _channel == null) {
      throw Exception('WebSocket未连接，无法发送消息');
    }

    try {
      final messageJson = jsonEncode(message.toJson());
      _channel!.sink.add(messageJson);
    } catch (e) {
      rethrow;
    }
  }

  /// 发送私聊消息
  Future<void> sendPrivateMessage(String toUserId, Map<String, dynamic> content) async {
    final message = WebSocketMessage(
      type: 'private',
      to: toUserId,
      content: content,
    );
    await sendMessage(message);
  }

  /// 发送群聊消息
  Future<void> sendGroupMessage(String pondId, Map<String, dynamic> content) async {
    final message = WebSocketMessage(
      type: 'group',
      pondId: pondId,
      content: content,
    );
    await sendMessage(message);
  }

  /// 发送管理员消息
  Future<void> sendAdminMessage(Map<String, dynamic> content) async {
    final message = WebSocketMessage(
      type: 'admin',
      content: content,
    );
    await sendMessage(message);
  }

  /// 启动心跳
  void _startHeartbeat() {
    _stopHeartbeat();
    _heartbeatTimer = Timer.periodic(_heartbeatInterval, (timer) {
      if (_isConnected && _channel != null) {
        try {
          final heartbeat = WebSocketMessage(
            type: 'heartbeat',
            content: {'timestamp': DateTime.now().millisecondsSinceEpoch},
          );
          _channel!.sink.add(jsonEncode(heartbeat.toJson()));
        } catch (e) {
        }
      }
    });
  }

  /// 停止心跳
  void _stopHeartbeat() {
    _heartbeatTimer?.cancel();
    _heartbeatTimer = null;
  }

  /// 安排重连
  void _scheduleReconnect() {
    if (_reconnectAttempts >= _maxReconnectAttempts) {
      return;
    }

    _reconnectTimer?.cancel();
    _reconnectTimer = Timer(_reconnectDelay, () {
      _reconnectAttempts++;
      connect();
    });
  }

  /// 断开连接
  Future<void> disconnect() async {
    
    _reconnectTimer?.cancel();
    _stopHeartbeat();
    
    await _subscription?.cancel();
    await _channel?.sink.close();
    
    _channel = null;
    _subscription = null;
    _isConnected = false;
    _isConnecting = false;
    _reconnectAttempts = 0;
    
    _connectionController.add(false);
  }

  /// 释放资源
  void dispose() {
    disconnect();
    _messageController.close();
    _connectionController.close();
  }
}

/// WebSocket通知服务 - 专门处理评论回复等通知
class WebSocketNotificationService {
  static final WebSocketNotificationService _instance = 
      WebSocketNotificationService._internal();
  factory WebSocketNotificationService() => _instance;
  WebSocketNotificationService._internal();

  final WebSocketService _wsService = WebSocketService();
  
  StreamSubscription? _messageSubscription;

  /// 初始化通知服务
  void initialize() {
    // 监听WebSocket消息
    _messageSubscription = _wsService.messageStream.listen(_handleNotification);
  }

  /// 处理通知消息
  void _handleNotification(WebSocketMessage message) {
    try {
      final content = message.content;
      final notificationType = content['notificationType'] as String?;
      
      switch (notificationType) {
        case 'comment_reply':
          _handleCommentReply(content);
          break;
        case 'post_reply':
          _handlePostReply(content);
          break;
        case 'like':
          _handleLike(content);
          break;
        case 'follow':
          _handleFollow(content);
          break;
        default:
      }
    } catch (e) {
    }
  }

  /// 处理评论回复通知
  void _handleCommentReply(Map<String, dynamic> content) {
    // 这里可以触发UI更新、显示通知等
    // 例如：显示系统通知、更新未读消息数量等
  }

  /// 处理帖子回复通知
  void _handlePostReply(Map<String, dynamic> content) {
  }

  /// 处理点赞通知
  void _handleLike(Map<String, dynamic> content) {
  }

  /// 处理关注通知
  void _handleFollow(Map<String, dynamic> content) {
  }

  /// 发送评论回复通知
  Future<void> sendCommentReplyNotification({
    required String toUserId,
    required String commentId,
    required String replyContent,
    required String postId,
    required String postTitle,
  }) async {
    final content = {
      'notificationType': 'comment_reply',
      'commentId': commentId,
      'replyContent': replyContent,
      'postId': postId,
      'postTitle': postTitle,
      'timestamp': DateTime.now().millisecondsSinceEpoch,
    };

    await _wsService.sendPrivateMessage(toUserId, content);
  }

  /// 发送帖子回复通知
  Future<void> sendPostReplyNotification({
    required String toUserId,
    required String postId,
    required String replyContent,
    required String postTitle,
  }) async {
    final content = {
      'notificationType': 'post_reply',
      'postId': postId,
      'replyContent': replyContent,
      'postTitle': postTitle,
      'timestamp': DateTime.now().millisecondsSinceEpoch,
    };

    await _wsService.sendPrivateMessage(toUserId, content);
  }

  /// 释放资源
  void dispose() {
    _messageSubscription?.cancel();
  }
}